﻿
using System;
using System.Collections.Generic;
using System.Linq;
using agsXMPP;
using agsXMPP.protocol.client;
using sharpxbot.Core.Configuration;
using sharpxbot.Core.Connection;
using sharpxbot.Core.Threading;
namespace sharpxbot.Core.Muc
{
    public class GroupChatContext : IActive, IGroupChatContext
    {
        public GroupChatContext(IConnection connection, IConfiguration configuration)
        {
            chats = new List<IGroupChat>();
            chatJids = new HashSet<string>();
            presenceCache = new PresenceCache();

            connection.OnPresence += new PresenceHandler(connection_OnPresence);

            foreach (IGroupChatConfiguration c in configuration.Rooms)
            {
                IGroupChat groupChat = new GroupChat(connection, c);

                chats.Add(groupChat);
                chatJids.Add(c.RoomJid);
            }
        }

        #region IActive Members

        public bool IsRunning { get; private set; }

        public void Start()
        {
            if (!IsRunning)
            {
                foreach (IGroupChat c in chats)
                {
                    ActiveHelper.StartIfActive(c);
                }
            }

            IsRunning = true;
        }

        public void Stop()
        {
            if (IsRunning)
            {
                foreach (IGroupChat c in chats)
                {
                    ActiveHelper.StopIfActive(c);
                }
            }
            IsRunning = false;
        }

        #endregion

        #region IGroupChatContext Members

        public Jid GetPrivateUserJid(Jid publicUserJid)
        {
            return presenceCache.GetPrivateJid(publicUserJid);
        }

        public void KickUser(string roomBareJid, string nick, string reason)
        {
            if (roomBareJid != null && !String.IsNullOrWhiteSpace(nick))
            {
                IGroupChat chat = FindGroupChat(roomBareJid);
                if (chat != null)
                {
                    chat.KickUser(new Jid(roomBareJid), nick, reason);
                }
            }
        }

        public void LeaveRoom(string roomBareJid, int timeout)
        {
            if (timeout <= 0 || String.IsNullOrWhiteSpace(roomBareJid))
                return;

            IGroupChat chat = FindGroupChat(roomBareJid);
            if (chat != null)
            {
                chat.LeaveRoom(timeout);
            }
        }

        #endregion

        #region Private methods

        void connection_OnPresence(object sender, Presence pres)
        {
            presenceCache.ProcessPresence(pres);
        }

        IGroupChat FindGroupChat(string bareJid)
        {
            if (String.IsNullOrWhiteSpace(bareJid))
                return null;

            return chats.Where(c => c.RoomJid.Bare == bareJid).FirstOrDefault();
        }

        #endregion

        #region Private fields

        ICollection<IGroupChat> chats;
        HashSet<string> chatJids;
        IPresenceCache presenceCache;

        #endregion
    }
}
